package com.paishen.peiniwan.frame;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.support.v4.app.NotificationCompat;
import android.widget.RemoteViews;
import android.widget.Toast;

import com.paishen.peiniwan.App;
import com.paishen.peiniwan.BusEvent;
import com.paishen.peiniwan.R;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import de.greenrobot.event.EventBus;

public class UpgradeService extends Service {

    public static final String Install_Apk = "Install_Apk";
    /********
     * download progress step
     *********/
    private static final int down_step_custom = 1;

    private static final int TIMEOUT = 100 * 1000;
    private static String down_url;
    private static final int DOWN_OK = 1;
    private static final int DOWN_ERROR = 0;

    private String app_name;

    private NotificationManager notificationManager;
    private Notification notification;
    // private Intent updateIntent;
    private PendingIntent pendingIntent;
    private RemoteViews contentView;

    public static void launch(Context context, String down_url) {
        Intent intent = new Intent(context, UpgradeService.class);
        intent.putExtra("Key_App_Name", context.getString(R.string.app_name));
        intent.putExtra("Key_Down_Url", down_url);
        context.startService(intent);
    }

    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        try {
            app_name = intent.getStringExtra("Key_App_Name");
            down_url = intent.getStringExtra("Key_Down_Url");
        } catch (Exception e) {
            Message message = new Message();
            message.what = DOWN_ERROR;
            handler.sendMessage(message);
        }

        FileUtil.createFile(app_name);

        if (FileUtil.isCreateFileSucess == true) {
            createThread();
        } else {
            Toast.makeText(this, R.string.frame_toast_qcrsdk, Toast.LENGTH_SHORT).show();
            /*************** stop service ************/
            stopSelf();
        }
        return START_STICKY;
    }

    /*********
     * update UI
     ******/
    private final Handler handler = new Handler() {
        @SuppressWarnings("deprecation")
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case DOWN_OK:

                    Uri uri = Uri.fromFile(FileUtil.updateFile);
                    Intent intent = new Intent(Intent.ACTION_VIEW);
                    intent.setDataAndType(uri, "application/vnd.android.package-archive");
                    pendingIntent = PendingIntent.getActivity(UpgradeService.this, 0, intent, 0);
                    makeNotification(pendingIntent, getString(R.string.frame_upgrade_success), -1);

                    EventBus.getDefault().post(new BusEvent( BusEvent.ACTION_UPGRADE_DOWNLOAD_FINISH));

                    installApk(UpgradeService.this);

                    // stopService(updateIntent);
                    /*** stop service *****/
                    stopSelf();
                    break;

                case DOWN_ERROR:
                    makeNotification(pendingIntent, getString(R.string.frame_upgrade_fail), -1);
                    /*** stop service *****/
                    // onDestroy();
                    stopSelf();
                    break;
            }
        }
    };

    public static void installApk(Context context) {
        // TODO Auto-generated method stub
        Uri uri = Uri.fromFile(FileUtil.updateFile);
        Intent intent = new Intent(Intent.ACTION_VIEW);

        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

        intent.setDataAndType(uri, "application/vnd.android.package-archive");
        context.startActivity(intent);
    }

    public void createThread() {
        new DownLoadThread().start();
    }

    private class DownLoadThread extends Thread {
        @Override
        public void run() {
            // TODO Auto-generated method stub
            Message message = new Message();
            try {
                long downloadSize = downloadUpdateFile(down_url, FileUtil.updateFile.toString());
                if (downloadSize > 0) {
                    // down success
                    message.what = DOWN_OK;
                    handler.sendMessage(message);
                }
            } catch (Exception e) {
                message.what = DOWN_ERROR;
                handler.sendMessage(message);
            }
        }
    }

    public static class FileInfo {
        public long totalSize;
        public long currSize;
        public int progress;

        public String getCurrDescription() {
            String t = String.format("%.2f", totalSize * 1f / 1048576) + "MB";
            String c;
            if (currSize < 1024) {
                c = currSize + "B";
            } else if (currSize < 1048576) {
                c = currSize / 1024 + "KB";
            } else {
                c = String.format("%.2f", currSize * 1f / 1048576) + "MB";
            }
            return c + "/" + t;
        }
    }

    /***
     * down file
     *
     * @return
     * @throws MalformedURLException
     */
    public long downloadUpdateFile(String down_url, String file) throws Exception {

        int down_step = down_step_custom;
        int totalSize;
        int downloadCount = 0;
        int updateCount = 0;

        InputStream inputStream;
        OutputStream outputStream;

        URL url = new URL(down_url);
        HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
        httpURLConnection.setConnectTimeout(TIMEOUT);
        httpURLConnection.setReadTimeout(TIMEOUT);
        totalSize = httpURLConnection.getContentLength();

        if (httpURLConnection.getResponseCode() == 404) {
            throw new Exception("download fail!");
        }

        inputStream = httpURLConnection.getInputStream();
        outputStream = new FileOutputStream(file, false);

        byte buffer[] = new byte[1024];
        int readsize = 0;

        while ((readsize = inputStream.read(buffer)) != -1) {


            outputStream.write(buffer, 0, readsize);
            downloadCount += readsize;
            /*** 1% up one time **/
            if (updateCount == 0 || (downloadCount * 100 / totalSize - down_step) >= updateCount) {
                updateCount += down_step;
//                contentView.setTextViewText(R.id.notificationPercent, updateCount + "%");
//                contentView.setProgressBar(R.id.notificationProgress, 100, updateCount, false);
//                notification.contentView = contentView;
//                notificationManager.notify(R.layout.frame_notification_upgrade, notification);
                makeNotification(null, getString(R.string.frame_upgrade_loading), updateCount);
                FileInfo fileInfo = new FileInfo();
                fileInfo.totalSize = totalSize;
                fileInfo.currSize = downloadCount;
                fileInfo.progress = updateCount;
                EventBus.getDefault().post(new BusEvent( BusEvent.ACTION_UPGRADE_DOWNLOAD_PROGRESS, fileInfo));
            }
        }
        if (httpURLConnection != null) {
            httpURLConnection.disconnect();
        }
        inputStream.close();
        outputStream.close();

        return downloadCount;
    }

    protected static int notifyID = 0525; // start notification id

    private final void makeNotification(PendingIntent pendingIntent, String summaryBody, int progress) {
        // create and send notificaiton
        Context appContext = App.i().getApplicationContext();
        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(appContext)
                .setSmallIcon(appContext.getApplicationInfo().icon)
                .setWhen(System.currentTimeMillis())
                .setAutoCancel(true);

        mBuilder.setContentTitle(getString(R.string.app_name) + getString(R.string.frame_upgrade));
        if (progress < 0) mBuilder.setDefaults(Notification.DEFAULT_VIBRATE);
        mBuilder.setTicker(getString(R.string.app_name));
        mBuilder.setContentText(summaryBody);
        if (progress >= 0) mBuilder.setProgress(100, progress, false);

        if (pendingIntent != null) mBuilder.setContentIntent(pendingIntent);
        Notification notification = mBuilder.build();

        notificationManager.notify(notifyID, notification);
    }

    public static class FileUtil {
        public static File updateDir = null;
        public static File updateFile = null;

        public static final String peiniwan = "peiniwan";

        public static boolean isCreateFileSucess;

        public static void createFile(String app_name) {
            if (android.os.Environment.MEDIA_MOUNTED.equals(android.os.Environment.getExternalStorageState())) {
                isCreateFileSucess = true;
                updateDir = new File(Environment.getExternalStorageDirectory() + "/" + peiniwan + "/");
                updateFile = new File(updateDir + "/" + app_name + ".apk");

                if (!updateDir.exists()) {
                    updateDir.mkdirs();
                }
                if (!updateFile.exists()) {
                    try {
                        updateFile.createNewFile();
                    } catch (IOException e) {
                        isCreateFileSucess = false;
                        e.printStackTrace();
                    }
                }
            } else {
                isCreateFileSucess = false;
            }
        }
    }
}
